package com.franklin.ideaplugin.easytesting.action;

import cn.hutool.core.util.CharUtil;
import com.franklin.ideaplugin.easytesting.ui.ExecuteMethodResultFormProvider;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;

import java.awt.event.MouseEvent;
import java.util.Objects;

/**
 * @author Ye Junhui
 * @since 2023/5/12
 */
public class ExecuteMethodAction extends AnAction {

    private static final Logger log = Logger.getInstance(ExecuteMethodAction.class);

    public ExecuteMethodAction() {
        super(AllIcons.Actions.Execute);
    }

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        PsiMethod psiMethod = findMethod(e);
        if (Objects.isNull(psiMethod)){
            return;
        }
        ExecuteMethodResultFormProvider executeMethodResultFormProvider = new ExecuteMethodResultFormProvider();
        executeMethodResultFormProvider.showExecuteMethodResultForm(psiMethod);
    }

    private PsiMethod findMethod(AnActionEvent e){
        PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
        Editor editor = e.getData(CommonDataKeys.EDITOR);
        if (Objects.isNull(psiFile) || Objects.isNull(editor)){
            return null;
        }

        //行数
        int line = EditorUtil.yPositionToLogicalLine(editor, ((MouseEvent) e.getInputEvent()).getPoint());

        int offset = findOffset(line + 1, psiFile.getText());
        if (offset < 0){
            return null;
        }
        PsiElement psiElement = psiFile.findElementAt(offset);
        PsiMethod psiMethod = PsiTreeUtil.getParentOfType(psiElement, PsiMethod.class);
        return psiMethod;
    }

    /**
     * 寻找目标行索引
     * @param targetLine
     * @param text
     * @return
     */
    private int findOffset(int targetLine,String text){
        int lineCount = 0;
        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);
            if (c == '\n'){
                lineCount++;
            }
            if (lineCount == targetLine){
                //往前找不为空的字符
                for (int j = i; j > 0; j--) {
                    char pre = text.charAt(j);
                    if (!CharUtil.isBlankChar(pre)){
                        return j;
                    }
                }
            }
        }
        return -1;
    }
}
